﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class DoStatement : BodiedStatement
{
    private readonly SyntaxToken _doKeywordToken;
    private Expression _conditionExpression;
    private SyntaxToken _loopKeywordToken;
    private SyntaxToken _whileOrUntilKeywordToken;

    internal DoStatement(SyntaxToken doKeywordToken, SyntaxNode? parent) :
        base(SyntaxKinds.DoStatement, parent)
    {
        SetChildField(ref _doKeywordToken, doKeywordToken);
        _conditionExpression = EmptyExpression.Default;
        _loopKeywordToken = SyntaxToken.Default;
        _whileOrUntilKeywordToken = SyntaxToken.Default;
    }


    public SyntaxToken DoKeywordToken => _doKeywordToken;

    public Expression ConditionExpression => _conditionExpression;

    public SyntaxToken LoopKeywordToken => _loopKeywordToken;

    /// <summary>
    ///     接收 while 或 until 关键字
    /// </summary>
    public SyntaxToken WhileOrUntilKeywordToken => _whileOrUntilKeywordToken;


    public DoStatement Update(SyntaxToken loopKeywordToken, SyntaxToken whileOrUntilKeywordToken,
        Expression conditionExpression)
    {
        Debug.Assert(loopKeywordToken.IsNode(SyntaxKinds.LoopKeywordToken));
        Debug.Assert(whileOrUntilKeywordToken.IsOneOfNode(SyntaxKinds.WhileKeywordToken,
            SyntaxKinds.UntilKeywordToken));
        SetChildField(ref _loopKeywordToken, SyntaxToken.IsNullOrEmpty, loopKeywordToken);
        SetChildField(ref _whileOrUntilKeywordToken, SyntaxToken.IsNullOrEmpty, whileOrUntilKeywordToken);
        SetChildField(ref _conditionExpression, Expression.IsEmptyExpression, conditionExpression);
        return this;
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, DoKeywordToken, LoopKeywordToken,
            WhileOrUntilKeywordToken, ConditionExpression);
        base.AcceptVisitor(visitor);
    }
}


public static partial class NodeFactory
{
    public static DoStatement CreateDoStatement(SyntaxNode? parent, SyntaxToken doKeywordToken)
    {
        Debug.Assert(doKeywordToken.IsNode(SyntaxKinds.DoKeywordToken));
        return new DoStatement(doKeywordToken, parent);
    }
}